<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    const eventBus = {
      allEvent: {},
      on(eventName, callback) {
        if (!this.allEvent[eventName]) {
          this.allEvent[eventName] = []
        }
        this.allEvent[eventName].push(callback)
      },
      emit(eventName, data) {
        this.allEvent[eventName] &&
          this.allEvent[eventName].forEach((callback) => callback(data))
      },
      off(eventName, callback) {
        if (this.allEvent[eventName]) {
          this.allEvent[eventName] = this.allEvent[eventName].filter(
            (item) => item !== callback
          )
        }
      },
      once(eventName, callback) {
        const fn = (data) => {
          callback(data)
          this.off(eventName, fn)
        }
        this.on(eventName, fn)
      },
    }
    eventBus.on('test', (data) => {
      console.log(data)
    })
    eventBus.emit('test', 'hello')
    eventBus.off('test', (data) => {
      console.log(data)
    })
  </script>
</html>
